

let localStream = null
let localPeerConnection = null
let remotePeerConnection = null

let localVideo = document.getElementById("localVideo")
let remoteVideo = document.getElementById("remoteVideo")

let startButton = document.getElementById("startButton")
let callButton = document.getElementById("callButton")
let hangupButton = document.getElementById("hangupButton")


startButton.disable  = false
callButton.disable   = false
hangupButton.disable = false;

startButton.onclick  = start;
callButton.onclick   = call;
hangupButton.onclick = hangup;

function log(text) {

    console.log("At time : " + (performance.now() / 1000).toFixed(3) + " --> " + text)
}

function successCallback(stream) {

    log("Received local stream")
    localVideo.srcObject = stream
    localStream = stream
    localVideo.play().then()
}

function start() {

    log("Requesting local stream")

    startButton.disable = true
    navigator.mediaDevices.getUserMedia({audio:true,video:true}).then(function (stream) {

        successCallback(stream)
    }).catch(function (error) {

        log("navigator getUserMedia error : ", error)
    })
}

function call() {

    callButton.disable = true
    hangupButton.disable = false

    log("starting call")

    let servers = null

    localPeerConnection = new RTCPeerConnection(servers)
    localPeerConnection.onicecandidate = gotLocalIceCandidate;

    remotePeerConnection = new RTCPeerConnection(servers)
    log("Created remote peer connection object remotePeerConnection")

    remotePeerConnection.onicecandidate = gotRemoteIceCandidate;
    remotePeerConnection.addEventListener('track', gotRemoteStream);
    localStream.getTracks().forEach(track => localPeerConnection.addTrack(track, localStream));
    localPeerConnection.createOffer().then(function (description) {

        localPeerConnection.setLocalDescription(description).then()
        log("Offer from localPeerConnection: \n" + description.sdp);

        remotePeerConnection.setRemoteDescription(description).then()
        remotePeerConnection.createAnswer().then(function (description) {

            gotRemoteDescription(description)

        }).catch(function (error) {


        })

    }).catch(function (error) {

        log("Failed to create signaling message : " + error.name)
    })
}

function hangup() {

    log("Ending call");

    // Close PeerConnection(s)
    localPeerConnection.close();
    remotePeerConnection.close();

    // Reset local variables
    localPeerConnection = null;
    remotePeerConnection = null;

    // Disable Hangup button
    hangupButton.disabled = true;

    // Enable Call button to allow for new calls to be established
    callButton.disabled = false;

}

function gotRemoteDescription(description) {

    remotePeerConnection.setLocalDescription(description).then()
    log("Answer from remotePeerConnection : \n" + description.sdp)
    localPeerConnection.setRemoteDescription(description).then()
}

function gotRemoteStream(event) {

    remoteVideo.srcObject = event.streams[0]
    log("Received remote stream");
}

function gotLocalIceCandidate(event) {
    
    if (event.candidate) {
        
        remotePeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate)).then(r => function (result) {

        }).catch(function (error) {

        })
        log("Local ICE candidate: \n" + event.candidate.candidate);
    }
}

function gotRemoteIceCandidate(event) {

    if (event.candidate) {

        localPeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate)).then()
        log("remote ICE candidate: \n" + event.candidate.candidate);

    }
}